/**
 * 传入是哪一个实例需要代理，代理的内容，和代理内容的命名空间
 * @param {*} vm 是哪一个 Due 实例
 * @param {*} data  data object/array
 * @param {*} namespace  命名空间
 */
export default function constructorProxy(vm, data, namespace) {
    let proxyData = null;
    if (data instanceof Array) { //是数组处理数组
        console.log('数组', data);
        proxyData = new Array(data.length);
        proxyData = proxyArray(vm, data, namespace);
        for (let i = 0; i < data.length; i++) {
            console.log(namespace)
            proxyData[i] = constructorProxy(vm, data[i], namespace);
        }
    } else if (data instanceof Object) { //是对象处理对象
        // console.log('对象');
        proxyData = objectProxy(vm, data, namespace);
    } else {
        throw new TypeError('data is not  object or Array');
    }
    return proxyData;
}
/**
 * 给每个属性添加 get set 方法
 * @param {*} vm  是哪一个 Due 实例
 * @param {*} data data object
 * @param {*} namespace 命名空间
 */
function objectProxy(vm, data, namespace) {
    let proxyData = {};
    //循环设置代理
    for (const key in data) {
        const proxyObject = {
            configurable: true,
            get: function () {
                return data[key];
            },
            set: function (value) {
                console.log(key, value, '变化了，要处理什么后面写');
                data[key] = value;
            },
        };
        Object.defineProperty(proxyData, key, proxyObject);
        //将代理挂载到当前 Due 实例上
        Object.defineProperty(vm, key, proxyObject);
        //判断当前值是不是一个引用值
        if (data[key] instanceof Object) {
            // console.log(getNamespace(namespace, key));
            //递归调用
            data[key] = constructorProxy(vm, data[key], getNamespace(namespace, key));
        }
    }

    return proxyData;
}
/**
 *得到完整的命名空间
 * @param {*} fatherName 上一级的命名空间
 * @param {*} sonName 当前的命名空间
 * @returns
 */
function getNamespace(fatherName, sonName) {
    console.log(fatherName + ' ' + sonName);
    if (fatherName === null || fatherName === '') {
        return sonName;
    } else if (sonName === null || sonName === '') {
        return fatherName;
    } else {
        return fatherName + '.' + sonName;
    }
}
/**
 * 给数组原型上添加代理
 * @param {*} vm  是哪一个 Due 实例
 * @param {*} data data object
 * @param {*} namespace 命名空间
 */
function proxyArray(vm, arr, namespace) {
    let obj = {
        eleType: 'Array',
        toString: function () {
            let res = '';
            for (let i = 0; i < arr.length; i++) {
                res += arr[i] + ', '
            }
            return res.slice(0, res.length - 2)
        },
        push() {},
        pop() {},
        shift() {},
        unshift() {},
    }
    definePropertyArray.call(vm, obj, 'push', namespace, vm)
    definePropertyArray.call(vm, obj, 'pop', namespace, vm)
    definePropertyArray.call(vm, obj, 'shift', namespace, vm)
    definePropertyArray.call(vm, obj, 'unshift', namespace, vm)
    obj.__proto__ = Array.prototype
    arr.__proto__ = obj
    return arr
}


function definePropertyArray(obj, arrFuncName, namespace, vm) {

    Object.defineProperty(obj, arrFuncName, {
        enumerable: true,
        configurable: true,
        value: function (...args) {
            const res = Array.prototype[arrFuncName].apply(this, args)
            console.log(arrFuncName, namespace, '变化了，要处理什么后面写');
            return res
        }

    })
}